home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / godelqc5.zip / SUBS.QC < prev    next >
Text File  |  1996-09-21  |  6KB  |  315 lines

  1. void() SUB_Null = {};
  2.  
  3. void() SUB_Remove = {remove(self);};
  4.  
  5. /*
  6. QuakeEd only writes a single float for angles (bad idea), so up and down are
  7. just constant angles.
  8. */
  9. vector() SetMovedir =
  10. {
  11.     if (self.angles == '0 -1 0')
  12.         self.movedir = '0 0 1';
  13.     else if (self.angles == '0 -2 0')
  14.         self.movedir = '0 0 -1';
  15.     else
  16.     {
  17.         makevectors (self.angles);
  18.         self.movedir = v_forward;
  19.     }
  20.     
  21.     self.angles = '0 0 0';
  22. };
  23.  
  24. /*
  25. ================
  26. InitTrigger
  27. ================
  28. */
  29. void() InitTrigger =
  30. {
  31. // trigger angles are used for one-way touches.  An angle of 0 is assumed
  32. // to mean no restrictions, so use a yaw of 360 instead.
  33.     if (self.angles != '0 0 0')
  34.         SetMovedir ();
  35.     self.solid = SOLID_TRIGGER;
  36.     setmodel (self, self.model);    // set size and link into world
  37.     self.movetype = MOVETYPE_NONE;
  38.     self.modelindex = 0;
  39.     self.model = "";
  40. };
  41.  
  42. /*
  43. =============
  44. SUB_CalcMove
  45.  
  46. calculate self.velocity and self.nextthink to reach dest from
  47. self.origin traveling at speed
  48. ===============
  49. */
  50. void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
  51. {
  52. local entity    stemp;
  53.     stemp = self;
  54.     self = ent;
  55.  
  56.     SUB_CalcMove (tdest, tspeed, func);
  57.     self = stemp;
  58. };
  59.  
  60. void(vector tdest, float tspeed, void() func) SUB_CalcMove =
  61. {
  62. local vector    vdestdelta;
  63. local float        len, traveltime;
  64.  
  65.     if (!tspeed)
  66.         objerror("No speed is defined!");
  67.  
  68.     self.think1 = func;
  69.     self.finaldest = tdest;
  70.     self.think = SUB_CalcMoveDone;
  71.  
  72.     if (tdest == self.origin)
  73.     {
  74.         self.velocity = '0 0 0';
  75.         self.nextthink = self.ltime + 0.1;
  76.         return;
  77.     }
  78.         
  79. // set destdelta to the vector needed to move
  80.     vdestdelta = tdest - self.origin;
  81.     
  82. // calculate length of vector
  83.     len = vlen (vdestdelta);
  84.     
  85. // divide by speed to get time to reach dest
  86.     traveltime = len / tspeed;
  87.  
  88.     if (traveltime < 0.1)
  89.     {
  90.         self.velocity = '0 0 0';
  91.         self.nextthink = self.ltime + 0.1;
  92.         return;
  93.     }
  94.     
  95. // set nextthink to trigger a think when dest is reached
  96.     self.nextthink = self.ltime + traveltime;
  97.  
  98. // scale the destdelta vector by the time spent traveling to get velocity
  99.     self.velocity = vdestdelta * (1/traveltime);    // qcc won't take vec/float    
  100. };
  101.  
  102. /*
  103. ============
  104. After moving, set origin to exact final destination
  105. ============
  106. */
  107. void()  SUB_CalcMoveDone =
  108. {
  109.     setorigin(self, self.finaldest);
  110.     self.velocity = '0 0 0';
  111.     self.nextthink = -1;
  112.     if (self.think1)
  113.         self.think1();
  114. };
  115.  
  116.  
  117. /*
  118. =============
  119. SUB_CalcAngleMove
  120.  
  121. calculate self.avelocity and self.nextthink to reach destangle from
  122. self.angles rotating 
  123.  
  124. The calling function should make sure self.think is valid
  125. ===============
  126. */
  127. void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
  128. {
  129. local entity        stemp;
  130.     stemp = self;
  131.     self = ent;
  132.     SUB_CalcAngleMove (destangle, tspeed, func);
  133.     self = stemp;
  134. };
  135.  
  136. void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
  137. {
  138. local vector    destdelta;
  139. local float        len, traveltime;
  140.  
  141.     if (!tspeed)
  142.         objerror("No speed is defined!");
  143.         
  144. // set destdelta to the vector needed to move
  145.     destdelta = destangle - self.angles;
  146.     
  147. // calculate length of vector
  148.     len = vlen (destdelta);
  149.     
  150. // divide by speed to get time to reach dest
  151.     traveltime = len / tspeed;
  152.  
  153. // set nextthink to trigger a think when dest is reached
  154.     self.nextthink = self.ltime + traveltime;
  155.  
  156. // scale the destdelta vector by the time spent traveling to get velocity
  157.     self.avelocity = destdelta * (1 / traveltime);
  158.     
  159.     self.think1 = func;
  160.     self.finalangle = destangle;
  161.     self.think = SUB_CalcAngleMoveDone;
  162. };
  163.  
  164. /*
  165. ============
  166. After rotating, set angle to exact final angle
  167. ============
  168. */
  169. void() SUB_CalcAngleMoveDone =
  170. {
  171.     self.angles = self.finalangle;
  172.     self.avelocity = '0 0 0';
  173.     self.nextthink = -1;
  174.     if (self.think1)
  175.         self.think1();
  176. };
  177.  
  178.  
  179. //=============================================================================
  180.  
  181. void() DelayThink =
  182. {
  183.     activator = self.enemy;
  184.     SUB_UseTargets ();
  185.     remove(self);
  186. };
  187.  
  188. /*
  189. ==============================
  190. SUB_UseTargets
  191.  
  192. the global "activator" should be set to the entity that initiated the firing.
  193.  
  194. If self.delay is set, a DelayedUse entity will be created that will actually
  195. do the SUB_UseTargets after that many seconds have passed.
  196.  
  197. Centerprints any self.message to the activator.
  198.  
  199. Removes all entities with a targetname that match self.killtarget,
  200. and removes them, so some events can remove other triggers.
  201.  
  202. Search for (string)targetname in all entities that
  203. match (string)self.target and call their .use function
  204.  
  205. ==============================
  206. */
  207. void() SUB_UseTargets =
  208. {
  209.     local entity t, stemp, otemp, act;
  210.  
  211. //
  212. // check for a delay
  213. //
  214.     if (self.delay)
  215.     {
  216.     // create a temp object to fire at a later time
  217.         t = spawn();
  218.         t.classname = "DelayedUse";
  219.         t.nextthink = time + self.delay;
  220.         t.think = DelayThink;
  221.         t.enemy = activator;
  222.         t.message = self.message;
  223.         t.killtarget = self.killtarget;
  224.         t.target = self.target;
  225.         return;
  226.     }
  227.     
  228.     
  229. //
  230. // print the message
  231. //
  232.     if (activator.classname == "player" && self.message != "")
  233.     {
  234.         centerprint (activator, self.message);
  235.         if (!self.noise)
  236.             sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  237.     }
  238.  
  239. //
  240. // kill the killtagets
  241. //
  242.     if (self.killtarget)
  243.     {
  244.         t = world;
  245.         do
  246.         {
  247.             t = find (t, targetname, self.killtarget);
  248.             if (!t)
  249.                 return;
  250.             remove (t);
  251.         } while ( 1 );
  252.     }
  253.     
  254. //
  255. // fire targets
  256. //
  257.     if (self.target)
  258.     {
  259.         act = activator;
  260.         t = world;
  261.         do
  262.         {
  263.             t = find (t, targetname, self.target);
  264.             if (!t)
  265.             {
  266.                 return;
  267.             }
  268.             stemp = self;
  269.             otemp = other;
  270.             self = t;
  271.             other = stemp;
  272.             if (self.use != SUB_Null)
  273.             {
  274.                 if (self.use)
  275.                     self.use ();
  276.             }
  277.             self = stemp;
  278.             other = otemp;
  279.             activator = act;
  280.         } while ( 1 );
  281.     }
  282.     
  283.  
  284. };
  285.  
  286.  
  287. /*
  288.  
  289. in nightmare mode, all attack_finished times become 0
  290. some monsters refire twice automatically
  291.  
  292. */
  293.  
  294. void(float normal) SUB_AttackFinished =
  295. {
  296.     self.cnt = 0;        // refire count for nightmare
  297.     if (skill != 3)
  298.         self.attack_finished = time + normal;
  299. };
  300.  
  301. float (entity targ) visible;
  302.  
  303. void (void() thinkst) SUB_CheckRefire =
  304. {
  305.     if (skill != 3)
  306.         return;
  307.     if (self.cnt == 1)
  308.         return;
  309.     if (!visible (self.enemy))
  310.         return;
  311.     self.cnt = 1;
  312.     self.think = thinkst;
  313. };
  314.  
  315.